package benchs

import (
	"context"
	"fmt"

	"gitee.com/chunanyong/zorm"
)

func init() {
	st := NewSuite("zorm")
	st.InitF = func() {
		st.AddBenchmark("Insert", 2000*ORM_MULTI, 0, ZormInsert)
		st.AddBenchmark("BulkInsert 100 row", 2000*ORM_MULTI, 0, ZormInsertMulti)
		st.AddBenchmark("Update", 2000*ORM_MULTI, 0, ZormUpdate)
		st.AddBenchmark("Read", 2000*ORM_MULTI, 0, ZormRead)
		st.AddBenchmark("MultiRead limit 1000", 2000*ORM_MULTI, 1000, ZormReadSlice)
		dataSourceConfig := zorm.DataSourceConfig{
			DSN:          ORM_SOURCE,
			DriverName:   "mysql",
			DBType:       "mysql",
			MaxIdleConns: ORM_MAX_IDLE,
			MaxOpenConns: ORM_MAX_CONN,
		}
		zorm.NewDBDao(&dataSourceConfig)
	}
}

func ZormInsert(b *B) {
	var m *Model
	wrapExecute(b, func() {
		initDB()
		m = NewModel()
	})
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		m.Id = 0
		//需要手动开启事务,匿名函数返回的error如果不是nil,事务就会回滚
		_, err := zorm.Transaction(context.Background(), func(ctx context.Context) (interface{}, error) {

			_, err := zorm.Insert(ctx, m)
			//如果返回的err不是nil,事务就会回滚
			return nil, err
		})
		if err != nil {
			fmt.Println(err)
			b.FailNow()
		}

	}

}

func ZormInsertMulti(b *B) {
	panic(fmt.Errorf("Don't support bulk insert"))
}

func ZormUpdate(b *B) {
	var m *Model
	wrapExecute(b, func() {
		initDB()
		m = NewModel()
		//需要手动开启事务,匿名函数返回的error如果不是nil,事务就会回滚
		zorm.Transaction(context.Background(), func(ctx context.Context) (interface{}, error) {
			if _, err := zorm.Insert(ctx, m); err != nil {
				fmt.Println(err)
				b.FailNow()
			}
			return nil, nil
		})
	})
	b.ResetTimer()
	//xo.Begin()
	zorm.Transaction(context.Background(), func(ctx context.Context) (interface{}, error) {
		for i := 0; i < b.N; i++ {
			if _, err := zorm.Update(ctx, m); err != nil {
				fmt.Println(err)
				xo.Rollback()
				b.FailNow()
			}
		}
		return nil, nil
	})
}

func ZormRead(b *B) {
	var m *Model
	wrapExecute(b, func() {
		initDB()
		m = NewModel()
		//需要手动开启事务,匿名函数返回的error如果不是nil,事务就会回滚
		_, err := zorm.Transaction(context.Background(), func(ctx context.Context) (interface{}, error) {
			_, err := zorm.Insert(ctx, m)
			return nil, err
		})

		if err != nil {
			fmt.Println(err)
			b.FailNow()
		}
	})
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		//查询Struct对象列表
		d := zorm.Query(context.Background(), zorm.NewSelectFinder(m.TableName()), m)
		if d != nil {
			fmt.Println(d.Error())
			b.FailNow()
		}
	}
}

func ZormReadSlice(b *B) {
	var m *Model
	wrapExecute(b, func() {
		initDB()
		m = NewModel()
		//需要手动开启事务,匿名函数返回的error如果不是nil,事务就会回滚
		zorm.Transaction(context.Background(), func(ctx context.Context) (interface{}, error) {
			for i := 0; i < b.L; i++ {
				m.Id = 0
				_, d := zorm.Insert(ctx, m)
				if d != nil {
					fmt.Println(d.Error())
					b.FailNow()
				}
			}
			return nil, nil
		})
	})
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		var models []Model
		page := zorm.NewPage()
		page.PageSize = b.L
		d := zorm.QuerySlice(context.Background(), zorm.NewSelectFinder(m.TableName()).Append(" WHERE id>0 order by id asc "), &models, page)
		if d != nil {
			fmt.Println(d.Error())
			b.FailNow()
		}
	}
}
